﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EraNet.Core;
using EraNet.Core.Caching;
using EraNet.Core.Data;
using EraNet.Core.Events;
using EraNet.Core.Model.SysManage;
using EraNet.Core.Model.Account;
using EraNet.Common;
using EraNet.Common.Files;
using System.Data;
using EraNet.Data;

namespace EraNet.Services.SysManage
{
    public partial class SysCardsService:ISysCardsService
    {
        #region Constants
        private const string SYSCARDS_BY_ID_KEY = "Era.SysCards.id-{0}";
        private const string SYSCARDS_PATTERN_KEY = "Era.SysCards.";
        #endregion

        #region Fields
        private readonly IRepository<SysCards> _syscardsRepository;
        private readonly IRepository<CardAllotLogs> _cardAllotLogsRepository;
        private readonly IRepository<Member> _memberRepository;
        private readonly ICacheManager _cacheManager;
        private readonly IEventPublisher _eventPublisher;
        #endregion
        
        #region Ctor
        public SysCardsService(IRepository<SysCards> syscardsRepository,IRepository<CardAllotLogs> cardAllotLogsRepository,IRepository<Member> memberRepository, ICacheManager cacheManager, IEventPublisher eventPublisher)
        {
            this._syscardsRepository = syscardsRepository;
            this._cardAllotLogsRepository = cardAllotLogsRepository;
            this._memberRepository = memberRepository;
            this._cacheManager = cacheManager;
            this._eventPublisher = eventPublisher;
        }
        #endregion

        #region Methods
        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns>0,失败 1，成功 2，存在重复</returns>
        public int InsertCard(SysCards model)
        {
            if (model == null)
                throw new ArgumentNullException("SysCards");

            if (_syscardsRepository.Table.Where(c => c.CardNo == model.CardNo).FirstOrDefault() != null) return 2;
            int rs= _syscardsRepository.Insert(model)>0?1:0;
            return rs;
        }

        /// <summary>
        /// 批量插入数据
        /// </summary>
        /// <param name="cards">卡的列表信息</param>
        /// <param name="IsAstrict">是否要限制长度，限制时不可以超过1000条</param>
        /// <returns></returns>
        public int InsertCards(IList<SysCards> cards, bool IsAstrict)
        {
            if (cards == null || cards.Count == 0)
                throw new ArgumentNullException("Null SysCards List");
            //限制一次只能1000条
            int pg = 1000;
            if (cards.Count < pg) pg = cards.Count;

            
            for (int i = pg; i < cards.Count; i++)
            {
                cards.Remove(cards[i]);
            }
            return _syscardsRepository.InsertList(cards);
        }

        /// <summary>
        /// 批量插入数据
        /// </summary>
        /// <param name="startNo">开始的卡号</param>
        /// <param name="Number">生成的数量</param>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public int InsertCards(string startNo, int Number, int clientId, bool IsAstrict)
        {
            if (startNo.Length != 10 && startNo.Length != 14)
                throw new ArgumentException("Erro Format for Card");
            string mark = startNo.Substring(0, startNo.Length - 8);
            int Num = Convert.ToInt32(startNo.Substring(startNo.Length - 8, 8));
            IList<SysCards> list = new List<SysCards>();
            if (IsAstrict) Number= Number > 1000 ? 1000 : Number;
            for (int i = 1; i <= Number; i++)
            {
                SysCards m = new SysCards();
                m.CardNo = Num + i;
                m.Markstr = mark;
                string salt=StrTools.RandomString(4, 0);
                m.CardPassword =  m.CardNo.ToString();
                m.CreateDate = DateTime.UtcNow;
                m.IsValid = true;
                m.CardType = 1;
                m.Salt = salt;
                m.AllotId = clientId;
                _syscardsRepository.Insert(m);
            }
            return 1;
        }

        /// <summary>
        /// 根据ID获取数据信息
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        public SysCards GetCardById(int cardId)
        {
            if (cardId <= 0)
                return null;
            var m = _syscardsRepository.GetById(cardId);
            return m;
        }

        /// <summary>
        /// 根据卡号获取信息
        /// </summary>
        /// <param name="cardNo"></param>
        /// <returns></returns>
        public SysCards GetCardByNo(string cardNo)
        {

            try
            {
                if (cardNo.Length > 12)
                    return null;
                string mark = cardNo.Substring(0, 2);

                int Num = Convert.ToInt32(cardNo.Substring(2,cardNo.Length - 2));
                var m = _syscardsRepository.Table.Where(c => c.Markstr == mark.ToUpper() && c.CardNo == Num).FirstOrDefault();
                return m;
            }
            catch (Exception)
            {
                return null;
            }
           
        }

        /// <summary>
        /// 根据卡号获取信息
        /// </summary>
        /// <param name="cardNo"></param>
        /// <returns></returns>
        public SysCards GetCardByNo(string cardNo, string cardPwd)
        {
            SysCards card = null;
            try
            {
                if (cardNo.Length >12)
                    return null;
                string mark = cardNo.Substring(0, 2);
                int Num = Convert.ToInt32(cardNo.Substring(2,cardNo.Length - 2));
                card = _syscardsRepository.Table.Where(c => c.Markstr == mark.ToUpper() && c.CardNo == Num && c.CardPassword == cardPwd).FirstOrDefault();
            }
            catch (Exception e)
            {
 
            }
            return card;
        }

        /// <summary>
        /// 获取单张未使用的学习卡
        /// </summary>
        /// <param name="schoolId">驾校ID</param>
        /// <returns></returns>
        public SysCards GetSingleCardBySchoolId(int schoolId)
        {
            SysCards card = _syscardsRepository.Table.Where(c => c.IsValid && c.SchoolId == schoolId).FirstOrDefault();
            return card;
        }

        /// <summary>
        /// 根据驾校ID获取所有学习卡信息 包括用户信息
        /// </summary>
        /// <param name="cardNo"></param>
        /// <returns></returns>
        public DataTable GetCardsBySchoolId(int schoolId, string cardNo, int pageIndex, int pageSize, out int count)
        {
            var query = from c in _syscardsRepository.Table
                        join cal in _cardAllotLogsRepository.Table
                            on c.Id equals cal.CardId into temp
                        from tt in temp.DefaultIfEmpty()
                        join m in _memberRepository.Table
                        on tt.MemberId equals m.Id into temp2
                        from tt2 in temp2.DefaultIfEmpty()
                        where c.SchoolId == schoolId
                        orderby tt.CreatedOnUtc descending
                        select new
                        {
                            cardId = c.Id,
                            cardNo = c.CardNo,
                            cardMarkstr=c.Markstr,
                            cardPwd = c.CardPassword,
                            cardActiveDate = tt.CreatedOnUtc,
                            memberName = tt2.Names,
                            idCard = tt2.IDCard
                            
                        };
            string mark = string.Empty;
            int Num = 0;
            if (cardNo != null)
            {
                if (cardNo.Length != 10 && cardNo.Length != 14)
                {
                    mark = "";
                    Num = 0;
                }
                else
                {
                    mark = cardNo.Substring(0, cardNo.Length - 8);
                    Num = Convert.ToInt32(cardNo.Substring(cardNo.Length - 8, 8));
                }
            }
            if (!string.IsNullOrEmpty(cardNo))
               query = query.Where(p => p.cardNo == Num && p.cardMarkstr == mark);
            count = query.Count();
            var cards = new PagedList<object>(query, pageIndex, pageSize);
            return Common.TypeConverter.LINQToDataTable(cards);
        }


        /// <summary>
        /// 激活卡
        /// </summary>
        /// <param name="cardNo"></param>
        /// <param name="cardPwd"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public int ActiveCard(string cardNo, string cardPwd, int userId)
        {
            //卡
            var m = GetCardByNo(cardNo);
            if (m == null) return 5;  //卡号不存在
            if (m.CardPassword != cardPwd) return 6; //密码错误
            if (m.IsValid == false) return 7;  //卡片已经被使用
            if(m.CardPassword !=  m.CardNo.ToString())return 8; //密码错误
            m.IsValid = false;
            _syscardsRepository.Update(m);
            //分配记录
            var logs = new CardAllotLogs();
            logs.CardId = m.Id;
            logs.CardNo =m.Markstr+m.CardNo.ToString();
            logs.CardPwd = cardPwd;
            logs.MemberId = userId;
            logs.CreatedOnUtc = DateTime.Now;
            _cardAllotLogsRepository.Insert(logs);
            //用户
            var member = _memberRepository.GetById(userId);
            int d=0;
            member.ExpireDate = DateTime.Now.AddMonths(6);
            _memberRepository.Update(member);

            return 10;
        }

        /// <summary>
        /// 更新学习卡
        /// </summary>
        /// <param name="SysCards">卡片实体</param>
        /// <returns>0-〉更新失败 1-〉更新成功</returns>
        public int UpdateSysCards(SysCards card)
        {
            if (card == null)
                throw new ArgumentNullException("SysCards");

            if (_syscardsRepository.Update(card) > 0)
            {

                //cache
                _cacheManager.RemoveByPattern(SYSCARDS_BY_ID_KEY);

                //event notification
                _eventPublisher.EntityUpdated(card);
                return 1;
            }
            return 0;
        }

        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="cardNo">卡号，由标识符（5位）和卡的编号（9位数字）组成</param>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <param name="isShowHide"></param>
        /// <returns></returns>
        public IPagedList<SysCards> GetAllCards(string cardNo, int pageSize, int pageIndex, bool isShowHide)
        {
            var query = _syscardsRepository.Table;
            if(cardNo!=null) 
            { 
                string No=cardNo.ToString();
                if(No.Length!=14) return null;
                string mark = No.Substring(9, 5);
                int Num = Convert.ToInt32(No.Substring(0, 8));
                query = query.Where(c => c.Markstr == mark && c.CardNo > Num);
            }
            if (!isShowHide)
                query = query.Where(c => c.IsValid == true);

            var cards = new PagedList<SysCards>(query, pageIndex, pageSize);
            return cards;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mark"></param>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        public IPagedList<SysCards> GetAllUsedCards(string mark, int pageSize, int pageIndex)
        {
            var query = _syscardsRepository.Table;
            if (!string.IsNullOrEmpty(mark))
            {
                query = query.Where(c => c.Markstr == mark);
            }

            var cards = new PagedList<SysCards>(query, pageIndex, pageSize);
            return cards;
        }

        /// <summary>
        /// 根据使用的卡和密码，获取关联的用户
        /// </summary>
        /// <param name="cardNo"></param>
        /// <param name="cardPwd"></param>
        /// <returns></returns>
        public Member GetMemberByCards(string cardNo,string cardPwd)
        {
            var query =_memberRepository.Table.Where(c => c.Status == 1);
            query = query.Join(_cardAllotLogsRepository.Table, x => x.Id, y => y.MemberId, (x, y) => new { member = x, cardlogs = y })
                  .Where(z => z.cardlogs.CardNo == cardNo.ToUpper()&&z.cardlogs.CardPwd==cardPwd)
                  .Select(z => z.member);

            query = query.OrderBy(c => c.CreateDate);
            var member = query.FirstOrDefault();
            return member;
        }


        /// <summary>
        /// 根据用户获取 管理的卡片信息
        /// </summary>
        /// <param name="cardNo"></param>
        /// <param name="cardPwd"></param>
        /// <returns></returns>
        public SysCards GetCardsByMemberId(int MemberId)
        {
            var query = _syscardsRepository.Table;
            query = query.Join(_cardAllotLogsRepository.Table, x => x.Id, y => y.CardId, (x, y) => new { cards = x, cardlogs = y })
                  .Where(z => z.cardlogs.MemberId==MemberId)
                  .Select(z => z.cards);

            var member = query.ToList().FirstOrDefault();
            return member;
        }

        /// <summary>
        /// 根据学员ID获取卡片分配记录
        /// </summary>
        /// <param name="cardNo"></param>
        /// <returns></returns>
        public List<CardAllotLogs> GetCardAllotLogs(int[] arrMemberId)
        {
            var queryResult = from p in _cardAllotLogsRepository.Table
                              where (arrMemberId).Contains(p.MemberId)
                              select p;
            return queryResult.ToList();
        }

        /// <summary>
        /// 根据ID获取数据信息
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        public CardAllotLogs GetCardAllotLogsById(int cardId)
        {
            if (cardId <= 0)
                return null;
            var m = _cardAllotLogsRepository.Table.Where(p => p.CardId == cardId).FirstOrDefault();
            return m;
        }

        /// <summary>
        /// 分配学习卡
        /// </summary>
        /// <param name="cal"></param>
        /// <returns></returns>
        public bool InsertCardAllotLog(CardAllotLogs cal, int cardId)
        {
            if (_cardAllotLogsRepository.Insert(cal) > 0)
            {
                SysCards card = _syscardsRepository.GetById(cardId);
                card.IsValid = false;
                _syscardsRepository.Update(card);
                return true;  //分配成功
            }
            else
                return false;

        }

        /// <summary>
        /// 更新学习卡记录
        /// </summary>
        /// <param name="cal"></param>
        /// <returns></returns>
        public bool UpdCardAllotLog(CardAllotLogs cal)
        {
            if (_cardAllotLogsRepository.Update(cal) > 0)
            {;
                return true;  //分配成功
            }
            else
                return false;

        }

        /// <summary>
        /// 判断卡片是已经分配学员
        /// </summary>
        /// <param name="cal"></param>
        /// <returns></returns>
        public bool isExistsByCardNo(string cardNo)
        {
            if (_cardAllotLogsRepository.Table.Where(p => p.CardNo == cardNo).Count() > 0)
            {
                return true;
            }
            else
                return false;

        }

        /// <summary>
        /// 修改实体 不需要再次查询
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public int MyUpdate(SysCards card)
        {
            var dataSettingsManager = new DataSettingsManager();
            var dataProviderSettings = dataSettingsManager.LoadSettings();
            EraObjectContext dbContext = new EraObjectContext(dataProviderSettings.DataConnectionString);
            dbContext.Entry(card).State = EntityState.Modified;
            return dbContext.SaveChanges();
        }



        /// <summary>
        /// 获取登录学员实体
        /// </summary>
        /// <returns></returns>
        public SysCards GetLoginSysCards()
        {
            SysCards dsa = null;
            Object obj = null;
            if (Utility.GetCookie("CardModel") != null && Utility.GetCookie("CardModel") != "")
                obj = (SysCards)SerializationHelper.BtyDeSerializer(Utility.GetCookie("CardModel"));
            if (obj != null) dsa = (SysCards)obj;
            return dsa;
        }

        #endregion
    }
}
